﻿using CXW.Core.Sharp.Gui;
using DevExpress.XtraBars;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

namespace CXW.Core.Sharp.Services
{
    //class MenuService<T> where T : class, IItemDescriptor
    class MenuService
    {
        BarManager barManager = null; BarSubItem _barSubItem = null;
        public MenuService(BarManager barManager)
        {
            this.barManager = barManager;
        }

        public void CreateMenuItems<T>(Bar bar, object owner, string addInTreePath, ref BarSubItem barSubItem)
        {//使用BarItem.AddItem方法必须先调用在递归,如果先递归后调用,启动时会报空指针错误
            foreach (IItemDescriptor descriptor in AddInTree.BuildItems<T>(addInTreePath, owner, false))
            {
                BarItem item = CreateMenuItemFromDescriptor(descriptor);
                barManager.Items.Add(item);
                bar.LinksPersistInfo.Add(new LinkPersistInfo(item));
            }
            barSubItem = _barSubItem;

            if (bar.LinksPersistInfo.Count == 0) { bar.Visible = false; }
        }

        BarItem CreateMenuItemFromDescriptor(IItemDescriptor descriptor)
        {
            Codon codon = descriptor.Codon;
            string type = codon.Properties.Contains("type") ? codon.Properties["type"] : "Command";

            switch (type)
            {
                case "Item":
                case "Check":
                case "Command":
                    BarButtonItemExt t = new BarButtonItemExt(codon);
                    if (type == "Check")
                    {
                        t.ButtonStyle = BarButtonStyle.Check;
                        t.GroupIndex = MenuCheckGroupIndex.Index(codon.Properties["group"]);
                    }

                    t.ItemClick += (sender, e) =>
                    {
                        ICommand cmd = CommandWrapper.CreateCommand(codon, descriptor.Caller);
                        if (cmd == null) { t.Enabled = false; }
                        else { cmd.Run(); }
                    };

                    return t;
                case "Menu":
                    BarSubItemExt item = new BarSubItemExt(codon);

                    CreateUnexpandedMenuItems(item, descriptor.SubItems);
                    item.Popup += (sender, e) =>
                    {
                        UpdateText(item.LinksPersistInfo);
                    };

                    if ("TreeSet" == codon.Id)
                    {
                        _barSubItem = item;
                    }
                    return item;
                default:
                    throw new NotSupportedException("unsupported menu item type : " + type);
            }
        }

        void CreateUnexpandedMenuItems(BarSubItemExt item, IList subItems)
        {
            foreach (IItemDescriptor des in subItems)
            {
                BarItem item2 = CreateMenuItemFromDescriptor(des);
                barManager.Items.Add(item2);
                item.LinksPersistInfo.Add(new LinkPersistInfo(item2));
            }
        }

        public static void UpdateText(Bar bar)
        {
            foreach (LinkPersistInfo o in bar.LinksPersistInfo)
            {
                IStatusUpdate cmi = o.Item as IStatusUpdate;
                if (cmi != null)
                {
                    cmi.UpdateText();
                }
            }
        }

        void UpdateText(LinksInfo linksInfo)
        {
            foreach (LinkPersistInfo o in linksInfo)
            {
                IStatusUpdate cmi = o.Item as IStatusUpdate;
                if (cmi != null)
                {
                    cmi.UpdateText();
                }
            }
        }
    }
    /// <summary></summary>
    class MenuCheckGroupIndex
    {
        private static Dictionary<string, int> dic = new Dictionary<string, int>();
        private static int _index = 0;
        /// <summary>根据配置的 group 属性获取 BarButtonItemExt.GroupIndex,相同 group[属性值不区分大小写] 得到相同的 BarButtonItemExt.GroupIndex</summary>
        /// <param name="group">group属性值,不区分大小写</param>
        public static int Index(string group)
        {
            group = group.ToLower();
            if (!dic.Keys.Contains(group))
            {
                if (string.IsNullOrWhiteSpace(group)) { dic.Add(group, 0); }
                else { dic.Add(group, ++_index); }
            }
            return dic[group];
        }
    }
}
